<!DOCTYPE html>
<script>
const first = () => (new Promise((resolve, reject) => {
    console.log(3);
    let p = new Promise((resolve, reject) => {
        console.log(7);
        setTimeout(() => {
            console.log(5);
            resolve(6);
        }, 0)
        resolve(1);
    });
    resolve(2);
    p.then((arg) => {
        console.log(arg);
    });

}));

first().then((arg) => {
    console.log(arg);
});
console.log(4);
/* 
    第一轮事件循环，先执行宏任务，主script，new Promise立即执行，输出 3，执行p这个new Promise操作，输出 7，发现setTimeout，将回调函数放入下一轮任务队列（Event Quene），p的then，暂且命名为then1，放入微任务队列，且first也有then，命名为then2，放入微任务队列。执行console.log(4),输出 4，宏任务执行结束。
    
    再执行微任务，执行then1,输出 1，执行then2,输出 3.

    第一轮事件循环结束，开始执行第二轮。第二轮事件循环先执行宏任务里面的，也就是setTimeout的回调，输出 5.resolve(6)不会生效，因为p的Promise状态一旦改变就不会再变化了。
*/
/* 
    Promise 构造函数是同步执行的，promise.then 中的函数是异步执行的。
    1.JS是单线程语言
    2.执行栈
    
    第一次事件轮循（srcipt, new Promise()先执行）
    宏任务：
    first() => 
        (1) 3, 
        (2) p =>
            7,
            setTimeout的回调函数 放入下一轮任务队列
            p.then() 放入微任务队列
        (3) first.then() 放入微任务队列
    console.log(4) => 4
    微任务：
    p.then() - resolve(1) => 1
    first.then() - resolve(2) => 2
    下一次事件循环
    setTimeout的回调函数 => 5
    p中new Promise(): resolve(1)已经改变状态，就不再执行resolve(6)了  promise 有 3 种状态：pending、fulfilled 或 rejected。状态改变只能是 pending->fulfilled 或者 pending->rejected，状态一旦改变则不能再变。
*/
</script>